//
//	File: AbstractMaterial.h
//
// Defines the abstract class for materials. Derived classes can use different implementations (using or not display lists).

#ifndef OY_ABSTRACTMATERIAL_H
#define OY_ABSTRACTMATERIAL_H


#include "MaterialRenderer.h"


class MaterialProperty;


// RenderPass
// This class represents a render pass.
class RenderPass
{
public :
	virtual ~RenderPass() {}
	virtual void PreRender() = 0;
	virtual void PostRender() = 0;
	virtual void AddProperty( MaterialProperty * property ) = 0;
	virtual void UpdateTexture(unsigned int texID, int unit) = 0;
};


// AbstractMaterial
// NOTE: A material is considered to be dynamic iff Update() should be called each frame.
//		 Thus, calling Update() on a non-dynamic material is redundant.
class AbstractMaterial
{
public :
	static const int INIT_RENDERPASS_ARRAY_NUM = 2;
	static const int INIT_DYNAMICMATERIAL_ARRAY_NUM	= 16;

	explicit AbstractMaterial() : 
		passes_(INIT_RENDERPASS_ARRAY_NUM),
		dynamic_( false ),
		transparent_( false ),
		mergeMode_( MM_Add )
	{
	}
	virtual ~AbstractMaterial();

	// public interface
	virtual void Clear() = 0;
	virtual void Update( float elapsedTime ) = 0;
	virtual void Clone( AbstractMaterial *pSrcMaterial ) = 0;
	inline int GetPassCount() const { return passes_.Count(); }
	void PreRender( int pass );
	void PostRender( int pass );
	inline bool IsDynamic() const { return dynamic_; }					// returns true if the material is dynamic
	inline bool IsTransparent() const { return transparent_; }			// returns true if the material is transparent
	inline EMaterialMerge GetMergeMode() const { return mergeMode_; }	// returns the default merging mode for this material
	static void UpdateDynamicMaterials( float elapsedTime );			// update the dynamic materials
	RenderPass* GetRenderPass(int PassID) { return passes_[PassID]; } 

protected :
	// protected interface
	void SetDynamic( bool dynamic );

	typedef OyArrayStack<RenderPass*> RenderPassList;
	RenderPassList		passes_;

	bool				transparent_;
	EMaterialMerge		mergeMode_;


private :
	typedef OyArrayStack<AbstractMaterial*> MaterialList;
	static MaterialList dynamicMaterials_;

	bool dynamic_;
};


#endif
